Skip to content

feat!: merge the v2 release line into main#1808

Draft
toiroakr wants to merge 777 commits into
mainfrom
v2
Draft

feat!: merge the v2 release line into main#1808
toiroakr wants to merge 777 commits into
mainfrom
v2

Conversation

@toiroakr

@toiroakr toiroakr commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Merges the v2 release line (SDK 2.0.0-next.x prereleases, published to the next dist-tag) into main, so the stable 2.0.0 ships from main.
  • This PR body tracks everything that must be done before (and immediately after) the merge — mostly cleanup of interim measures that only existed because v2 was a long-lived branch.

Pre-merge checklist

Branch sync & CI

Release & versioning

  • Decide the fate of the open 1.x release PR Version Packages #1786 (changeset-release/main): publish a final 1.x release before merging, or close it.
  • Land or close the v2 prerelease PR Version Packages (next) #1804 (changeset-release/v2) so no release PR is in flight when the merge happens.
  • Create a v1 maintenance branch from the current main tip before merging, so 1.x patch releases stay possible (@tailor-platform/sdk is at 1.79.0 on main).
  • Exit changesets pre mode (pnpm changeset pre exit, which removes .changeset/pre.json) so the first release from main publishes the stable 2.0.0 to the latest dist-tag. Decide whether to run it on v2 right before merging or on main immediately after.
  • Verify the release workflow's "Resolve pending codemod version boundaries" step (pnpm codemod:resolve-pending) behaves correctly for the first stable (non-next) release. No codemod currently uses V2_NEXT_PENDING, but any codemod added before the stable release will.
  • Reword .changeset/v2-baseline.md — it still says prereleases are published to the next dist-tag; the stable 2.0.0 changelog entry should describe the stable install/upgrade path instead.
  • Confirm @tailor-platform/sdk-plugin-tailordb-erd (0.1.0-next.0) is ready to leave prerelease — it exits pre mode together with the SDK.

CI workflow cleanup (in this PR or immediately after merge)

  • Drop v2 from branch triggers: test.yml, ci.yml, release.yml, pkg-pr-new.yml, erd-schema.yml, lockfile-audit.yml, check-license.yml, template-tests.yml, skills-sync-check.yml, sdk-metrics.yml.
  • Restore the branches: [main] filter on sdk-metrics.yml's pull_request trigger (removed so it ran for v2-based PRs).
  • Optionally tighten changeset-check.yml's skip condition back from startsWith(head.ref, 'changeset-release/') to the exact changeset-release/main (it was broadened for the v2 release branch).
  • Remove the link-check.yml exclusion for example/resolvers/startWorkflow.ts — the file exists on main once this merges.

tailor-platform/actions

  • Release a tagged version of tailor-platform/actions that supports the v2 CLI, then repin erd-schema-export / erd-schema-preview / erd-schema-comment in erd-schema.yml (currently pinned to the unreleased v2-branch SHA 0bd69a0f…) and remove the # pinact:skip-file marker.
  • Verify the actions version scaffolded by tailor setup (ACTIONS_SHA / ACTIONS_VERSION = v1.7.0 in packages/sdk/src/cli/commands/setup/templates.ts) works with the renamed tailor CLI; bump once a v2-compatible actions release exists.
  • Re-evaluate the "Stub ERD plugin bin target" workaround in erd-schema.yml (pnpm bin-linking workaround for the workspace plugin package) once the plugin install story settles.

Docs (after the stable publish)

  • Replace the @next install instructions with the stable tag: packages/sdk-plugin-tailordb-erd/README.md, packages/sdk/docs/cli/tailordb.md + tailordb.template.md, packages/sdk/docs/github-actions.md (then run pnpm docs:update).
  • Regenerate packages/sdk/docs/migration/v2.md (pnpm codemod:docs:update) once all codemod version boundaries are final.

Repo housekeeping (after merge)

Notes

  • Merge this PR with a merge commit (not squash): the branch contains merges from main, and the release workflow relies on the consumed-changeset history staying intact.

toiroakr and others added 30 commits July 3, 2026 17:47
# Conflicts:
#	packages/create-sdk/CHANGELOG.md
#	packages/create-sdk/package.json
#	packages/sdk/CHANGELOG.md
#	packages/sdk/docs/cli/setup.md
#	packages/sdk/docs/runtime.md
#	packages/sdk/docs/testing.md
#	packages/sdk/knip.json
#	packages/sdk/package.json
#	packages/sdk/src/cli/commands/api.test.ts
#	packages/sdk/src/cli/commands/deploy/resolver.test.ts
#	packages/sdk/src/cli/commands/deploy/resolver.ts
#	packages/sdk/src/cli/commands/function/logs.test.ts
#	packages/sdk/src/cli/commands/generate/service.test.ts
#	packages/sdk/src/cli/commands/setup/check.ts
#	packages/sdk/src/cli/commands/setup/index.ts
#	packages/sdk/src/cli/commands/setup/lock.test.ts
#	packages/sdk/src/cli/crashreport/sanitize.test.ts
#	packages/sdk/src/cli/crashreport/sender.test.ts
#	packages/sdk/src/cli/services/auth/bundler.test.ts
#	packages/sdk/src/cli/services/tailordb/hooks-validate-bundler.ts
#	packages/sdk/src/cli/services/workflow/ast-transformer.test.ts
#	packages/sdk/src/cli/services/workflow/bundler.test.ts
#	packages/sdk/src/cli/services/workflow/trigger-transformer.ts
#	packages/sdk/src/cli/shared/context.test.ts
#	packages/sdk/src/cli/shared/context.ts
#	packages/sdk/src/cli/shared/function-script-download.test.ts
#	packages/sdk/src/cli/shared/runtime-exprs.test.ts
#	packages/sdk/src/cli/shared/type-generator.test.ts
#	packages/sdk/src/cli/shared/type-generator.ts
#	packages/sdk/src/configure/services/auth/index.test.ts
#	packages/sdk/src/configure/services/resolver/resolver.test.ts
#	packages/sdk/src/configure/services/tailordb/schema.test.ts
#	packages/sdk/src/configure/services/workflow/job.test.ts
#	packages/sdk/src/configure/services/workflow/job.ts
#	packages/sdk/src/configure/types/type.test.ts
#	packages/sdk/src/parser/service/tailordb/field.ts
#	packages/sdk/src/runtime/file.test.ts
#	packages/sdk/src/runtime/globals.ts
#	packages/sdk/src/vitest/workflow-runtime.ts
#	packages/sdk/tsdown.config.ts
# Conflicts:
#	example/package.json
#	package.json
#	packages/create-sdk/package.json
#	packages/sdk-codemod/package.json
#	packages/sdk/CHANGELOG.md
#	packages/sdk/src/cli/commands/login.test.ts
#	packages/sdk/src/cli/commands/login.ts
#	packages/sdk/src/cli/commands/profile/update.ts
#	packages/sdk/src/cli/commands/user/pat/list.test.ts
#	packages/sdk/src/cli/commands/user/pat/user.ts
#	packages/sdk/src/cli/commands/user/switch.test.ts
#	packages/sdk/src/cli/commands/user/switch.ts
#	packages/sdk/src/cli/shared/context.test.ts
#	packages/sdk/src/cli/shared/context.ts
#	packages/sdk/src/cli/shared/type-generator.ts
#	packages/sdk/src/configure/services/auth/types.ts
#	packages/sdk/src/configure/services/tailordb/schema.ts
#	packages/sdk/tsdown.config.ts
#	pnpm-lock.yaml
# Conflicts:
#	packages/create-sdk/CHANGELOG.md
#	packages/create-sdk/package.json
#	packages/sdk/CHANGELOG.md
#	packages/sdk/docs/cli/application.md
#	packages/sdk/package.json
#	packages/sdk/src/cli/commands/deploy/deploy.ts
#	packages/sdk/src/cli/commands/deploy/executor.ts
#	packages/sdk/src/cli/commands/deploy/index.ts
Running `tailor <name>` for an unknown subcommand execs an external
`tailor-<name>` binary resolved from the project's node_modules/.bin
(nearest first) or PATH, forwarding all following args. Works for unknown
subcommands nested under a known command too (`tailor tailordb erd` ->
`tailor-tailordb-erd`). Builtins always take precedence, matching stops at
the first unknown segment, and a command that defines its own run is never
replaced.

Before dispatching, the CLI injects the current platform context as env so
plugins do not re-implement auth or re-resolve the active workspace:
TAILOR_PLATFORM_TOKEN, TAILOR_PLATFORM_URL, TAILOR_PLATFORM_OAUTH2_CLIENT_ID,
TAILOR_PLATFORM_WORKSPACE_ID, TAILOR_PLATFORM_USER, TAILOR_CONFIG_PATH,
TAILOR_VERSION, and TAILOR_BIN. Token, workspace, and user are best-effort so
auth-free plugins still run when not logged in.

Adds `tailor auth token` (print a valid access token, refreshing it if
expired, for plugins/scripts) and `tailor plugin list` (list discovered
plugins and where they resolve from). The root --help notes point users to
`tailor plugin list`.
Adapts CLI plugin support to v2's refactored client API (getPlatformBaseUrl/getOAuth2ClientId) and docs template format, and marks the plugin feature as beta in the CLI help, docs, and changeset.
Resolve conflicts from parallel test refactors on v2: reconcile
test.each table-driven rewrites with this branch's UUIDString/
DateString/Timestamp scalar tightening, restoring date/datetime
edge-case coverage that the v2 shrink pass had dropped.
…e-types

feat(sdk): tighten Tailor field output types
buildPluginEnv now resolves the active profile's platform URL and OAuth2 client ID (via loadPlatformClientConfig) so a plugin dispatched under a profile targeting a non-default platform receives a consistent URL/token/workspace instead of the default endpoint.

Also hardens Windows executable handling: buildSpawnTarget runs .com like a native .exe and dispatches .ps1 through PowerShell, isExecutable rejects files whose extension is not in PATHEXT (so data files are not listed as plugins), and the PATHEXT fallback includes .COM.
resolvePlugin now rejects plugin names containing path separators or NUL before joining them into a filesystem path, so a name like `../evil` cannot escape the `<cli>-` prefix and resolve an unintended executable.

Also enables the plugin test suites on Windows (cross-platform capture fixture using a `.cmd` wrapper) and adds a dedicated `Plugin tests (Windows)` CI job, since the main SDK unit suite only runs on Linux and the Windows PATHEXT/`.cmd`/`.ps1` dispatch branches were previously untested. Corrects the auth/token readonly-guard comment to note it may refresh via the OAuth server and persist tokens locally, without mutating workspace/platform state.
node:fs globSync yields backslash paths on Windows, which vitest treats as invalid include globs (backslash is an escape in the matcher), so the Plugin tests (Windows) job resolved zero files and exited 1. Normalize the classified unit-test paths to forward slashes so discovery and the vitest run <file> filter work on win32 (no-op on POSIX).
Replace the separator-sensitive positional file filter (which resolved zero files on Windows) with a dedicated "unit-plugin" vitest project that includes only the CLI plugin test. The Windows CI job selects it with --project unit-plugin, and the unit* glob still runs it on Linux; it is excluded from the general unit split so it does not run twice. Reverts the earlier forward-slash include normalization, now unnecessary.
feat(cli): plugin dispatch with shared auth (root & nested)
Register the v2/strict-scalar-strings migration guidance for the strict
UUID/date/datetime/time/decimal field string types introduced on v2. The
entry documents the new scalar shapes and is*/parse*/assert*String helpers
in the generated migration guide, and flags likely-affected files
(getDB / toISOString / mockIdp usage and old "mock-id" fixtures) for
LLM-assisted review during tailor upgrade.
Pattern-scoped review flags miss projects whose only breakage does not
mention getDB / toISOString / mockIdp (e.g. invalid id fixtures), so drop
the suspicious patterns and let the runner emit the prompt as project-wide
guidance.
feat(codemod): add v2 strict scalar strings migration entry
# Conflicts:
#	.github/workflows/changeset-check.yml
#	docs/getting-started.md
#	llm-challenge/package.json
#	package.json
#	packages/create-sdk/CHANGELOG.md
#	packages/create-sdk/package.json
#	packages/sdk-codemod/CHANGELOG.md
#	packages/sdk-codemod/package.json
#	packages/sdk/CHANGELOG.md
#	packages/sdk/package.json
#	packages/sdk/src/cli/commands/deploy/resolver.ts
#	packages/sdk/src/configure/services/tailordb/schema.ts
#	packages/sdk/src/configure/types/type.ts
#	pnpm-lock.yaml
Field and type-level hooks and validators are now compiled into a single per-type create/update script. Hooks receive a `now` (Date) shared across every field hooked in the same operation, so multiple fields can be stamped with one identical timestamp.
… preserve Create-input optionality

The platform derives GraphQL Create-input optionality from the presence of a field-level create hook, not from type_hook. Emit a passthrough create hook (`_value`) per field so required hooked fields stay optional in input; the real shared-now logic in type_hook runs afterward and overwrites the value.
…oto field

Add .default() builder method for TailorDBField with TypeLevelError
type guards. Regenerate proto bindings to use optionalOnCreate instead
of field-level hook placeholder, resolving type_hook coexistence conflict.
…y field validators

- Add type-level validate function form to .validate() accepting (args, issues) callback
- Field validators now return string (error) | void (pass) instead of [fn, message] tuple
- Type-safe field path autocomplete for issues() via DottedPaths utility type
- Full pipeline: configure -> parser -> bundler -> snapshot -> manifest
- Hook functions use newRecord/oldRecord args matching platform _input/_oldRecord variables
- Field validators receive { newValue, oldValue } only
…to single function

Replace Hooks<F> (per-field mapping) with TypeHook<F> ({ create?, update? })
where each function receives { input, oldRecord, invoker, now } and returns
partial field overrides. Also rename HookFn parameter from newRecord to input
since hooks operate on pre-record input.

- Add TypeHookFn and TypeHook types to configure/services/tailordb/types.ts
- Change .hooks() builder to store _typeHook instead of distributing to fields
- Add typeHook to Zod schema and regenerate types
- Update createTailorDBHook test helper to apply type-level hooks
- Update buildTypeScripts to accept options object with typeHookExpr
- Update example and template code to new hooks API
…tax validators

- Simplify ValidateFn from { newValue, oldValue } to { value } only
- Remove Validators<F> record-syntax overload from type-level validate
- Block .default() on optional fields with TypeLevelError
- Migrate all examples, templates, and tests to new API
Fields with .default() now produce Generated<T> in Kysely types,
matching the optionalOnCreate behavior sent to the platform.
Update inventory-management template to reflect type-level hook
migration (totalPrice no longer has a per-field hook).
Sync FieldMetadataSchema (used by resolver/executor/workflow fields) with
DBFieldMetadataSchema: add default key and update validate to accept
Function[] only. Regenerate example migrations for hooks drift and update
zinfer-generated types.
chore: rename sdk-tailordb-erd-plugin package to sdk-plugin-tailordb-erd
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a2fa202

The changes in this PR will be included in the next version bump.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

# Conflicts:
#	.agents/skills/e2e-setup/SKILL.md
#	.github/workflows/changeset-check.yml
#	.github/workflows/pkg-pr-new.yml
#	.gitignore
#	packages/create-sdk/scripts/prepare-templates.js
#	packages/create-sdk/templates/inventory-management/src/executor/checkInventory.ts
#	packages/sdk/docs/services/auth.md
#	packages/sdk/knip.ts
#	packages/sdk/package.json
#	packages/sdk/src/cli/commands/generate/service.ts
#	packages/sdk/src/cli/commands/generate/watch/index.test.ts
#	packages/sdk/src/cli/commands/generate/watch/index.ts
#	packages/sdk/src/cli/index.ts
#	packages/sdk/src/cli/lib.ts
#	packages/sdk/src/cli/services/application.ts
#	packages/sdk/src/cli/services/auth/bundler.ts
#	packages/sdk/src/cli/services/resolver/bundler.ts
#	packages/sdk/src/cli/services/tailordb/service.ts
#	packages/sdk/src/cli/services/workflow/bundler.test.ts
#	packages/sdk/src/cli/services/workflow/bundler.ts
#	packages/sdk/src/cli/shared/start-context.ts
#	packages/sdk/src/cli/shared/type-generator.test.ts
#	packages/sdk/src/cli/shared/type-generator.ts
#	packages/sdk/src/configure/services/auth/types.ts
#	packages/sdk/src/parser/service/auth/schema.ts
#	packages/sdk/tsdown.config.ts
#	pnpm-lock.yaml
@pkg-pr-new

pkg-pr-new Bot commented Jul 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/@tailor-platform/create-sdk@a2fa202
pnpm add https://pkg.pr.new/@tailor-platform/eslint-plugin-sdk@a2fa202
pnpm add https://pkg.pr.new/@tailor-platform/sdk@a2fa202
pnpm add https://pkg.pr.new/@tailor-platform/sdk-plugin-tailordb-erd@a2fa202

commit: a2fa202

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

🗺️ ERD preview

Self-contained ERD viewer HTML built for this run. Each viewer can switch between the current schema and a diff against base branch main.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

…kout

changesets/action's github-api commit mode leaves a first-release
package's CHANGELOG.md as an untracked file, which the release PR branch
tracks — so gh pr checkout aborted with 'untracked working tree files
would be overwritten' once eslint-plugin-sdk entered the release. Clean
untracked files after the hard reset before switching branches.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

toiroakr and others added 3 commits July 18, 2026 17:46
… ships

The Workflow/WorkflowJob .trigger() -> .start() rename lands in the next
prerelease, not 2.0.0-next.6 — next.6 has no .start() method, so surfacing
the migration guidance for next.6 targets would point users at an API that
does not exist there. Use the V2_NEXT_PENDING sentinel so the release
workflow resolves the boundary to the version the rename actually ships in.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

toiroakr and others added 3 commits July 19, 2026 15:51
…are optional

Machine user attribute keys mirroring field optionality made the generated
Attributes interface's properties optional, which broke the IdP/TailorDB
permission condition helpers two ways: the homomorphic key-extraction types
leaked undefined into the user operand key unions (failing assignability to
the generated permission types even for _loggedIn-only conditions), and keys
derived from optional fields stopped being accepted as operands. Strip the
optional modifier and exclude undefined from the value side so optional
attribute fields stay valid operand keys with undefined-free unions.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown

Code Metrics Report (packages/sdk)

main (4675aa4) #1808 (c14eab1) +/-
Coverage 74.5% 77.0% +2.5%
Code to Test Ratio 1:0.4 1:0.4 +0.0
Details
  |                    | main (4675aa4) | #1808 (c14eab1) |  +/-  |
  |--------------------|----------------|-----------------|-------|
+ | Coverage           |          74.5% |           77.0% | +2.5% |
  |   Files            |            457 |             443 |   -14 |
  |   Lines            |          16953 |           16478 |  -475 |
+ |   Covered          |          12636 |           12703 |   +67 |
+ | Code to Test Ratio |          1:0.4 |           1:0.4 |  +0.0 |
  |   Code             |         113445 |          115436 | +1991 |
+ |   Test             |          52708 |           54874 | +2166 |

Code coverage of files in pull request scope (70.0% → 73.9%)

Skip file coverages because there are too many files (267)

SDK Configure Bundle Size

main (4675aa4) #1808 (c14eab1) +/-
configure-index-size 32.17KB 31.26KB -0.91KB
dependency-chunks-size 29.88KB 24.97KB -4.91KB
total-bundle-size 62.05KB 56.22KB -5.83KB

Runtime Performance

main (4675aa4) #1808 (c14eab1) +/-
Generate Median 3,134ms 2,008ms -1,126ms
Generate Max 3,297ms 2,033ms -1,264ms
Apply Build Median 3,150ms 2,047ms -1,103ms
Apply Build Max 3,169ms 2,166ms -1,003ms

Type Performance (instantiations)

main (4675aa4) #1808 (c14eab1) +/-
tailordb-basic 43,881 40,190 -3,691
tailordb-optional 4,451 4,535 84
tailordb-relation 6,220 3,854 -2,366
tailordb-validate 753 666 -87
tailordb-hooks 5,279 5,499 220
tailordb-object 12,547 16,345 3,798
tailordb-enum 1,486 1,538 52
resolver-basic 9,252 12,107 2,855
resolver-nested 26,119 35,406 9,287
resolver-array 18,059 24,043 5,984
executor-schedule 4,310 4,481 171
executor-webhook 949 1,120 171
executor-record 6,762 4,532 -2,230
executor-resolver 4,090 5,777 1,687
executor-operation-function 937 1,108 171
executor-operation-gql 945 1,116 171
executor-operation-webhook 956 1,127 171
executor-operation-workflow 1,798 1,921 123

Reported by octocov

@github-actions

Copy link
Copy Markdown

Code Metrics Report (packages/sdk)

main (4675aa4) v2 (a2fa202) +/-
Coverage 74.5% 77.0% +2.5%
Code to Test Ratio 1:0.4 1:0.4 +0.0
Details
  |                    | main (4675aa4) | v2 (a2fa202) |  +/-  |
  |--------------------|----------------|--------------|-------|
+ | Coverage           |          74.5% |        77.0% | +2.5% |
  |   Files            |            457 |          443 |   -14 |
  |   Lines            |          16953 |        16478 |  -475 |
+ |   Covered          |          12636 |        12703 |   +67 |
+ | Code to Test Ratio |          1:0.4 |        1:0.4 |  +0.0 |
  |   Code             |         113445 |       115436 | +1991 |
+ |   Test             |          52708 |        54874 | +2166 |

Code coverage of files in pull request scope (70.0% → 73.9%)

Skip file coverages because there are too many files (267)

SDK Configure Bundle Size

main (4675aa4) v2 (a2fa202) +/-
configure-index-size 32.17KB 31.26KB -0.91KB
dependency-chunks-size 29.88KB 24.97KB -4.91KB
total-bundle-size 62.05KB 56.22KB -5.83KB

Runtime Performance

main (4675aa4) v2 (a2fa202) +/-
Generate Median 3,134ms 2,589ms -545ms
Generate Max 3,297ms 2,627ms -670ms
Apply Build Median 3,150ms 2,636ms -514ms
Apply Build Max 3,169ms 2,701ms -468ms

Type Performance (instantiations)

main (4675aa4) v2 (a2fa202) +/-
tailordb-basic 43,881 40,190 -3,691
tailordb-optional 4,451 4,535 84
tailordb-relation 6,220 3,854 -2,366
tailordb-validate 753 666 -87
tailordb-hooks 5,279 5,499 220
tailordb-object 12,547 16,345 3,798
tailordb-enum 1,486 1,538 52
resolver-basic 9,252 12,107 2,855
resolver-nested 26,119 35,406 9,287
resolver-array 18,059 24,043 5,984
executor-schedule 4,310 4,481 171
executor-webhook 949 1,120 171
executor-record 6,762 4,532 -2,230
executor-resolver 4,090 5,777 1,687
executor-operation-function 937 1,108 171
executor-operation-gql 945 1,116 171
executor-operation-webhook 956 1,127 171
executor-operation-workflow 1,798 1,921 123

Reported by octocov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants